package com.bsoft.gol.hcb.service.templateSheet.processor.transProcessor.impl;

import com.bsoft.gol.hcb.service.templateSheet.entity.TemplateSheet;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.bsoft.gol.hcb.service.templateSheet.processor.transProcessor.TransProcessor;
import com.bsoft.gol.hcb.service.templateSheet.rpc.IMcVisitRpcService;
import com.bsoft.gol.hcb.service.templateSheet.rpc.IVisitModuleRpcService;
import com.bsoft.gol.hcb.service.templateSheet.rpc.entity.VisitModule;
import com.bsoft.gol.hcb.service.templateSheet.utils.XmlUtils;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service("bsXmlTransProcessor")
public class BsXmlTransProcessor implements TransProcessor {

    @Autowired
    private IVisitModuleRpcService visitModuleRpcService;

    @Autowired
    private IMcVisitRpcService mcVisitRpcService;

    @Override
    public TemplateSheet inTrans(TemplateSheet templateSheet) throws Exception {
        Map<String,Object> bsXmlMap = new HashMap<>();
        String serviceMethod = getServiceMethod(templateSheet.getTemplateId(), "get");
        //生成MsgHeader xmlMap
        bsXmlMap.put("MsgHeader",getMsgHeaderMap(serviceMethod));
        templateSheet.getSheetParam().put("recordId",templateSheet.getRecordId());
        //生成MsMsgBody xmlMap
        bsXmlMap.put("MsgBody",templateSheet.getSheetParam());

        //生成xml报文
        StringBuilder sb = new StringBuilder();
        String bsXmlReq = XmlUtils.mapToXml(bsXmlMap, "BSXml", sb);

        //发送请求
        String bsXmlResp = mcVisitRpcService.mcVisitRecord(serviceMethod,bsXmlReq,serviceMethod);

//        String bsXmlResp = inMock(templateSheet.getRecordId(),templateSheet.getTemplateId());

        return parseBsXmlResp(bsXmlResp,templateSheet);
    }

    @Override
    public TemplateSheet outTrans(TemplateSheet templateSheet) throws Exception {
        Map<String,Object> bsXmlMap = new HashMap<>();
        String serviceMethod = getServiceMethod(templateSheet.getTemplateId(), "save");
        //生成MsgHeader xmlMap
        bsXmlMap.put("MsgHeader",getMsgHeaderMap(serviceMethod));

        //recordId 加入到 msgbody节点下
        if (!StringUtils.isEmpty(templateSheet.getRecordId())){
            templateSheet.getSheetParam().put("recordId",templateSheet.getRecordId());
        }
        bsXmlMap.put("MsgBody",templateSheet.getSheetParam());

        //生成xml报文
        StringBuilder sb = new StringBuilder();
        String bsXmlReq = XmlUtils.mapToXml(bsXmlMap, "BSXml", sb);

        //发送请求
        String bsXmlResp = mcVisitRpcService.mcVisitRecord(serviceMethod,bsXmlReq,serviceMethod);

        //mock
//        String bsXmlResp = outMock(templateSheet.getRecordId(), templateSheet.getTemplateId(), templateSheet.getSheetParam());

        return parseBsXmlResp(bsXmlResp,templateSheet);
    }

    public Map<String,Object> getMsgHeaderMap(String ServiceMethod) throws Exception {
        Map<String, Object> msgHeaderMap = new HashMap<>();
        msgHeaderMap.put("Sender", "GOL");
        msgHeaderMap.put("ServiceType", "service");
        msgHeaderMap.put("ServiceMethod", ServiceMethod);
        msgHeaderMap.put("MsgVersion", "4.0");
        return msgHeaderMap;
    }

    private String getServiceMethod(Integer templateId, String methodType) throws Exception {
        VisitModule visitModule = visitModuleRpcService.getById(templateId);
        if (visitModule == null){
            throw new Exception("未找到id为:"+templateId+"的表单模版");
        }
        if (StringUtils.isEmpty(visitModule.getPlatformMethodName())){
            throw new Exception("id为:"+templateId+"的表单模版未设置第三方平台方法参数");
        }
        return "ODS_"+methodType+visitModule.getPlatformMethodName();
    }

    private TemplateSheet parseBsXmlResp(String xml, TemplateSheet templateSheet) throws Exception {
        if (StringUtils.isEmpty(xml)){
            throw new Exception("请求集成平台未得到响应或响应内容为空");
        }

        Element msgBody;
        try {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
            Element bsXml = document.getRootElement();
            msgBody = bsXml.element("MsgBody");
        }catch (Exception e){
            throw new Exception("解析响应报文失败，"+xml, e);
        }

        if (msgBody == null){
            throw new Exception("请求集成平台未得到响应体，"+xml);
        }

        String code = msgBody.element("Code").getText();
        if (StringUtils.isEmpty(code) || !"200".equals(code)){
            String detail = msgBody.element("Detail").getText();
            log.info("请求集成平台响应未成功，Code:{}，Detail:{}",code,detail);
            throw new Exception(detail);
        }

        Element data = msgBody.element("Data");
        if (data != null){
            String recordId = data.element("RecordId").getText();
            templateSheet.setRecordId(recordId);

            Map<String, Object> dataMap = (Map<String, Object>) XmlUtils.xmlToMap(data.asXML()).get("data");
            templateSheet.setSheetParam(dataMap);
        }


        return templateSheet;
    }

    //////////////////////////////////mock/////////////////////////////////////////////////////////
    private Map<String,Map> mockMap = new HashMap<>();
    private String outMock(String recordId, Integer templateId, Map paramMap){
        if (StringUtils.isEmpty(recordId)){
            recordId = UUID.randomUUID().toString();
        }
        String key = recordId+"$"+templateId;
        paramMap.put("recordId",recordId);
        mockMap.put(key,paramMap);

        String respXml = "<BSXml>\n" +
                "    <MsgHeader>\n" +
                "        <Sender>GOL</Sender>\n" +
                "        <ServiceType>service</ServiceType>\n" +
                "        <MsgType>111</MsgType>\n" +
                "        <MsgVersion>4.0</MsgVersion>\n" +
                "        <ServiceMethod>aaaa</ServiceMethod>\n" +
                "    </MsgHeader>\n" +
                "    <MsgBody>\n" +
                "        <Code>200</Code>\n" +
                "        <Data>\n" +
                "            <RecordId>"+recordId+"</RecordId>\n" +
                "        </Data>\n" +
                "    </MsgBody>\n" +
                "</BSXml>";
        return respXml;
    }

    private String inMock(String recordId, Integer templateId){
        String key = recordId+"$"+templateId;
        Map map = mockMap.get(key);
        String msgbodyXml = "";
        if (map == null){
            msgbodyXml = "<MsgBody><Code>500</Code><Detail>未查找到记录</Detail></MsgBody>";
        }else {
            StringBuilder sb = new StringBuilder();
            msgbodyXml = XmlUtils.mapToXml(map, "Data", sb);
            msgbodyXml = "<MsgBody><Code>200</Code>"+ msgbodyXml+"</MsgBody>";
        }

        String respXml = "<BSXml>\n" +
                "    <MsgHeader>\n" +
                "        <Sender>GOL</Sender>\n" +
                "        <ServiceType>service</ServiceType>\n" +
                "        <MsgType>111</MsgType>\n" +
                "        <MsgVersion>4.0</MsgVersion>\n" +
                "        <ServiceMethod>aaaa</ServiceMethod>\n" +
                "    </MsgHeader>\n" +msgbodyXml+
                "</BSXml>";
        return respXml;
    }

    public static void main(String[] args) throws Exception {
        String xml = "<BSXml>\n" +
                "    <MsgHeader>\n" +
                "        <Sender>GOL</Sender>\n" +
                "        <ServiceType>service</ServiceType>\n" +
                "        <MsgType>111</MsgType>\n" +
                "        <MsgVersion>4.0</MsgVersion>\n" +
                "        <ServiceMethod>aaaa</ServiceMethod>\n" +
                "    </MsgHeader>\n" +
                "    <MsgBody>\n" +
                "        <Code>200</Code>\n" +
                "        <Data>\n" +
                "            <RecordId>vst202209109921</RecordId>\n" +
                "        </Data>\n" +
                "    </MsgBody>\n" +
                "</BSXml>";
        TemplateSheet templateSheet = new TemplateSheet();
        new BsXmlTransProcessor().parseBsXmlResp(xml,templateSheet);
    }
}

/**
 * 疾病史数据转换示例
 *       TemplateSheet templateSheet = new TemplateSheet();
 *         HashMap<String,Object> plist = new HashMap<>();
 *             HashMap<String,Object> map = new HashMap<>();
 *                 List<HashMap<String,Object>> peop  = new ArrayList<>();
 *                     HashMap<String,Object> p1 = new HashMap<>();
 *                     p1.put("name","zhangshan");
 *                     p1.put("age",14);
 *                 peop.add(p1);
 *                     HashMap<String,Object> p2 = new HashMap<>();
 *                     p2.put("name","lisi");
 *                     p2.put("age",18);
 *                 peop.add(p2);
 *             map.put("people",peop);
 *         plist.put("plist",map);
 *       templateSheet.setSheetParam(plist);
 */